Desenvolvimento para Dispositivos Móveis
Aula 07
Prof. Dr. Raulcézar Alves
raulcezar@gmail.com

Projeto UatZap

  • Chat de texto para usuários cadastrados no App.
  • Utilizar Firebase para autenticar e armazenar mensagens.

Projeto UatZap

Projeto UatZap

Modificações activity_main.xml

Modificações activity_main.xml

						
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    tools:context=".MainActivity">
     <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>
    <!-- ADD-->
    <ListView
        android:id="@+id/listViewMsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <TextView
        android:text="Mensagem"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/enviar"
        android:text="enviar"
        android:onClick="enviarMsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <include layout="@layout/content_main" />

   </LinearLayout>
						
					

ListView

  • A ListView é um grupo de exibições que exibe uma lista de itens roláveis.
  • Os itens da lista são inseridos automaticamente na lista usando um Adapter que obtém conteúdo de uma origem como uma matriz ou consulta de banco de dados e converte cada resultado de item em uma exibição, que é colocada na lista.
  • Existem vários tipos de ListViews, cada uma serve para uma situação diferente e para resolver problemas diversos em seus aplicativos.

ListView

  • A memória de dispositivos móveis é fixa e extremamente limitada.
  • É utilizada para armazenar diversos tipos de dados: textos, fotos, vídeos, audios, etc.
  • Além disso, é compartilhada por todos os aplicativos do seu dispositivo, inclusive o próprio SO (Android).

ListView

  • Apps devem fazer uso inteligente de memória, caso contrário eles podem travar sua execução e também a de outros.
  • Imagine um App que mostra todos os seus contatos de uma vez, por exemplo 1.000. Seria necessário 1.000 TextView na tela ocupando memória, sendo que conseguiriamos ver apenas 10.

ListView

  • Uma estratégia é reciclagem de Views.
  • Podemos criar apenas a quantidade de Views que conseguimos ver na tela, e a medida em que rolamos a lista, dados que não podem mais ser vistos são removidos das Views para dar espaço aos novos.

ListView

  • Para utilizar essa estratégia e exibir listas de maneira eficiente, utilizamos algum tipo de ListView (tela) juntamente com um Adapter (java).
  • Adapter é responsável por gerenciar e adaptar os dados nas Views, e até criá-las se necessário.
  • Existem vários tipos de Adapter, um dos mais utilizados é o ArrayAdapter que pode manipular dados com base em Arrays ou java.util.List.

ListView

    Existem dois métodos importantes nos Adapters para fazer a atualização dos dados e avisar as ListViews da tela que algo mudou:
  • notifyDataSetChanged(): É chamado se os dados tiverem sido alterados ou se houver novos dados disponíveis.
  • notifyDataSetInvalidated(): É chamado se os dados não estiverem mais disponíveis.

ListView

  • A ListView é um dos componentes mais utilizados para listar dados na plataforma Android de forma eficiente.
  • Basicamente ela organiza os dados um seguido do outro em formato vertical com a opção de rolagem.
  • Para utilizar a ListView, primeiro deve-se adicionar o componente no XML da activity (tela).

ListView

  • Depois, no controle Java da activity, no método onCreate(), deve-se recuperar o componente pelo ID para utilizá-lo mais tarde, de preferência utilizando o padrão ViewHolder que vimos.

ListView

  • Os dados a serem apresentados na ListView podem estar armazenados em um Array, como mostrado abaixo, ou em um Java List.
  • Estes dados podem ser estáticos, ou terem vindo por exemplo de uma Base de dados dinamicamente.

ListView

  • É necessário instanciar um ArrayAdapter tipando ele com dados do tipo String neste caso.
  • No construtor, passe os seguintes parâmetros: Context, ID do layout e a Array de dados.
  • No exemplo, é utilizado o layout android.R.layout.simple_list_item_1, padrão para a linha da ListView.
  • Depois, o Adapter é adicionado dentro da ListView utilizando o método setAdapter().

ListView

    Resumindo:
  • dizemos que a ListView da tela (@+id/listview)
  • é ligada ao atributo listview no Java
  • gerenciado pelo adaptador adapter
  • que administra os dados a serem exibidos do vetor dados.

Modificações MainActivity.java

Modificações MainActivity.java

Modificações MainActivity.java

Modificações activity_main.xml

							
package mobile.pitagoras.uatzap;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
    private FirebaseAuth mAuth;
    private DatabaseReference dbr;//ADD
    private ViewHolder vh = new ViewHolder();//ADD
    private ArrayList<String> listMsg = new ArrayList<String>();//ADD
    private ArrayAdapter arrayAdpt;//ADD
    private FirebaseUser user;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mAuth = FirebaseAuth.getInstance();
        user = mAuth.getCurrentUser();
        if (user != null) {
            Toast.makeText(getApplicationContext(), "Bem vindo de volta " + user.getEmail() + "!", Toast.LENGTH_LONG).show();
        } else {
            Intent intent = new Intent(this, LoginActivity.class);
            startActivity(intent);
            finish();
        }
        this.vh.msg = (EditText) findViewById(R.id.msg);//ADD
        this.vh.listViewMsg = (ListView) findViewById(R.id.listViewMsg);//ADD
        arrayAdpt = new ArrayAdapter(this,android.R.layout.simple_list_item_1,listMsg);//ADD
        this.vh.listViewMsg.setAdapter(this.arrayAdpt);//ADD
        dbr = FirebaseDatabase.getInstance().getReference().getRoot();//ADD
        dbr.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Set<String> set =  new HashSet<String>();
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    ds.getValue();
                    set.add(ds.getValue().toString());
                }
                arrayAdpt.clear();
                arrayAdpt.addAll(set);
                arrayAdpt.notifyDataSetChanged();
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
    }
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_exit) {
            mAuth.signOut();
            startActivity(new Intent(this, LoginActivity.class));
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public void enviarMsg(View view) {
        android.text.format.DateFormat df = new android.text.format.DateFormat();
        String data = df.format("dd/MM/yyyy hh:mm", new java.util.Date()).toString();
        String valor = user.getEmail()+": \n"+this.vh.msg.getText().toString()+" \n"+data;
        String chave = dbr.push().getKey();
        dbr.child(chave).setValue(valor);
    }

    private class ViewHolder{//ADD
        ListView listViewMsg;
        EditText msg;
    }

}

						
					

UatZap

Verifique permissão de internet no AndroidManifest.xml

							
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mobile.pitagoras.uatzap">
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.INTERNET" /><!-- ADD-->
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".LoginActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
						
					

Verifique as versões do Firebase (preferência 16.0.4)

							
apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "mobile.pitagoras.uatzap"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    //noinspection GradleCompatible
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.google.firebase:firebase-auth:16.0.4'
    implementation 'com.google.firebase:firebase-core:16.0.4'
    implementation 'com.google.firebase:firebase-database:16.0.4'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

apply plugin: 'com.google.gms.google-services'